import lombok.Data;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

//深拷贝对象，super.clone()方法是浅拷贝
@Data
public class ConcretePrototype implements Cloneable, Serializable {
    private int age;
    private String name;
    private List<String> hobbies;

    //浅拷贝
    @Override
    protected ConcretePrototype clone() throws CloneNotSupportedException {
        try{
            return (ConcretePrototype)super.clone();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //深拷贝
    public ConcretePrototype deepClone(){
        try{
            //字节输出流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //对象输出流
            ObjectOutputStream objectOutput = new ObjectOutputStream(byteArrayOutputStream);
            //写入对象
            objectOutput.writeObject(this);

            //字节输入流
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            //对象输入流
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            //读入对象
            return (ConcretePrototype)objectInputStream.readObject();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", hobbies=" + hobbies +
                '}';
    }


    public static void main(String[] args) {
        //创建原型对象
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setAge(18);
        concretePrototype.setName("Tom");
        List<String> hobbies = new ArrayList<String>();
        hobbies.add("书法");
        hobbies.add("美术");
        concretePrototype.setHobbies(hobbies);
        System.out.println(concretePrototype);
        //等号赋值传递的是引用
        hobbies.add("美术");
        System.out.println(concretePrototype);

        try{
            ConcretePrototype concretePrototype1 = concretePrototype.clone();
            concretePrototype1.getHobbies().add("英语");
            System.out.println(concretePrototype);
            System.out.println(concretePrototype1);

            ConcretePrototype concretePrototype2 = concretePrototype.deepClone();
            concretePrototype2.getHobbies().add("数学");
            System.out.println(concretePrototype);
            System.out.println(concretePrototype2);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
